<?php

namespace app\api\controller;

use app\common\controller\Api;
use think\Session;
use think\Db;

/**
 * 会员接口
 */
class Task extends Api
{
    protected $noNeedLogin = ['TaskURStatus', 'TaskCancelAorder','TaskORStatus','TaskORStatus2','getOrderCount','sendUserAdmin','TaskchangeRoomStatus','TaskCheckout','getAreaDown','getcityArea','getRooms'];
    protected $noNeedRight = '*';
    protected $hid = null;
    protected $adminId = null;

    public function _initialize()
    {
        parent::_initialize();

        $this->hid = Session::get("admin")["hotelid"];
        $this->adminId = Session::get("admin")["id"];
    }

    /**
     * 定时任务1 执行更新房源状态  暂定 jsw 2021-8-2 增加了库存 暂时不需要了
     * 将房源根据预定的时间 自动更新为 不可预定 状态
     * 只要将可预定房间的时间改成当前时间 即可 当用户退房后，则将可预定时间放开
     */
    public function TaskURStatus()
    {
        try{
            $time = time();
            $where["beforeTime"] = array("lt",$time);

            //判断订单表是否有下个预定 如果有 时间为下一个订房时间前两个小时，如果没有,beforeTime则为空
            $house = db("house");
            $houselist = $house->where("h_statusText = 'normal' and beforeTime <> ''")->where($where)->field("id,h_statusText,beforeTime")->select();

            $order =  db("order");
            foreach ($houselist as $v){
                //如果订单里只有一个在预约中的 那么这个时间就是和房间预约的时间是一个人
               $orderList = $order->where(["room_id"=>$v["id"],"pay_status"=>"1"])->field("stime")->order("stime asc")->select();
               $len = count($orderList);
               if($len < 2 ){
                   $rdata["h_statusText"] = "reserve";
                   $rdata["updatetime"] = time();
                   $rdata["beforeTime"] = Null;
               }else{
                   $rdata["h_statusText"] = "reserve";
                   $rdata["updatetime"] = time();
                   $rdata["beforeTime"] = $orderList[1]["stime"] - 7200;
               }

                $houseRes = $house->where(["id"=>$v["id"]])->update($rdata);
                file_put_contents("autoHouseStatusSuccess.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$houseRes.PHP_EOL, FILE_APPEND);

            }
            return "success";

        }catch (\think\exception\PDOException $e){

            file_put_contents("autoHouseStatusError.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$e->getMessage().PHP_EOL, FILE_APPEND);
        }

    }


    /**
     * 定时任务2 执行更新订单状态 未支付 金额回退 写入数据 不走微信退款，无真实金额交易
     * 将未支付的订单在规定时间内未支付自动修改为已取消
     */
    public function TaskORStatus()
    {
        try{
            $time = time();
            $where["pay_status"] = "0";
            $where["payend_time"] = array("lt",$time);
            $order = db("order");
            $orderList = $order->where($where)->select();
            if($orderList){
                foreach ($orderList as $v){
                    $upd["upd_time"] = time();
                    $upd["cancel_time"] = time();
                    $upd["pay_status"] = "4";
                    $upd["return_money"] = $v['all_money'];

                    $res = $order->where(["id"=>$v["id"]])->update($upd);
                    file_put_contents("autoPayCancelSuccess.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$res.PHP_EOL, FILE_APPEND);
                }

            }

            return "success";
        }catch (\think\exception\PDOException $e){
            file_put_contents("autoPayCancelError.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$e->getMessage().PHP_EOL, FILE_APPEND);
        }
    }


    /**
     * 定时任务2 活动订单到期取消
     */
    public function TaskCancelAorder()
    {
        try{
            $time = time();
            $where["pay_status"] = "0";
            $where["payend_time"] = array("lt",$time);
            $order = db("orderactivity");
            $orderList = $order->where($where)->select();
            if($orderList){
                foreach ($orderList as $v){
                    $upd["upd_time"] = $time;
                    $upd["cancel_time"] = $time;
                    $upd["pay_status"] = "4";
                    $res = $order->where(["id"=>$v["id"]])->update($upd);
                    file_put_contents("TaskCancelAorder.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$res.PHP_EOL, FILE_APPEND);
                }

            }

            return "success";
        }catch (\think\exception\PDOException $e){
            file_put_contents("TaskCancelAorderError.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$e->getMessage().PHP_EOL, FILE_APPEND);
        }
    }


    /**
     * 定时任务3 执行更新订单状态 已预定 到了 入住时间 如果用户没有办理入住，程序自动将该订单 变成 入住状态
     * jsw 2021-8-2 新增
     */
    public function TaskORStatus2()
    {
        try{
            $time = time();
            $where["pay_status"] = "1";
            $where["moveinto_time"] = array("lt",$time);
            $order = db("order");
            $house = db("house");
            $orderList = $order->where($where)->field("id,room_id")->select();

            if($orderList){
                foreach ($orderList as $v){

                    $upd["upd_time"] = $time;
                    $upd["pay_status"] = "2";//入住
                    //更新订单
                    $res = $order->where(["id"=>$v["id"]])->update($upd);

                    //考虑到房间显示问题，这里就不修改房间状态
                    //$uphouse["h_statusText"] = "using";//入住
                    //$uphouse["updatetime"] = $time;
                    //$res2 = $house->where(["id"=>$v["room_id"]])->update($uphouse);
                    file_put_contents("autoruzhuSuccess.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$res.PHP_EOL, FILE_APPEND);
                }

            }

            return "success";
        }catch (\think\exception\PDOException $e){
            file_put_contents("autoruzhulError.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$e->getMessage().PHP_EOL, FILE_APPEND);
        }
    }



    /**
     * 定时任务4  实时查询订单，如果有预定了某个房间 到这天后 自动把房间变成预定状态，则该房间将不会被显示在小程序端
     * jsw 2021-8-2 新增  2021-09-10 废弃 如果把房间变成了预定，那么小程序端无论什么时间都不能显示，所以必须是动态根据时间来动态房间状态，reserve using 两个状态都要动态
     */
    public function TaskchangeRoomStatus()
    {
        try{
            $time = time();
            $where["pay_status"] = "1";
            $order = db("order");
            $house = db("house");
            $orderList = $order->where($where)->field("id,room_id,stime")->select();
            if($orderList){
                foreach ($orderList as $v){
                    //如果当前时间到了下单的开始时间所在的天 则自动把房源改为预定中
                    $stime = strtotime(date("Y-m-d",$v['stime']));
                    if($time >= $stime){
                        $upd["updatetime"] = $time;
                        $upd["h_statusText"] = "reserve";//入住
                        //更新房间
                        $res2 = $house->where(["id"=>$v["room_id"]])->update($upd);
                        file_put_contents("TaskchangeRoomStatus.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$res2.PHP_EOL, FILE_APPEND);
                    }
                }

            }

            return "success";
        }catch (\think\exception\PDOException $e){
            file_put_contents("autoruzhulError.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$e->getMessage().PHP_EOL, FILE_APPEND);
        }
    }



    /**
     * 定时任务5 实时查询订单是否到期 到期后自动退房
     * jsw 2021-8-2 新增
     */
    public function TaskCheckout()
    {
        try{
            $time = time();
            $where["pay_status"] = "2";
            $where["etime"] = array("lt",$time);
            $order = db("order");

            $orderList = $order->where($where)->select();

            if($orderList){
                foreach ($orderList as $v){
                    $res = $this->checkOut($v);
                }

            }

            return "all-success";
        }catch (\think\exception\PDOException $e){
            file_put_contents("TaskCheckouterr.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$e->getMessage().PHP_EOL, FILE_APPEND);
        }
    }



    /**
     * 定时任务3 房费到期提醒，发送给用户和酒店配置的手机
     * 将未支付的订单在规定时间内未支付自动修改为已取消
     */
    public function sendUserAdmin(){
        try{
            $time = time();
            $where["pay_status"] = "2";
            $where["sendmsg_time"] = array("lt",$time);
            $where["sendmsg_flag"] = 0;//未发送
            $order = db("order");
            $orderList = $order->where($where)->select();

            if($orderList){
                foreach ($orderList as $v){
                    //发送短信 用户
                    if($v["h_phone"]){
                        $res = sendmsg($v["user_phone"]);
                    }
                    //发送酒店
                    if($v["user_phone"] && $v["user_name"]){
                        $res2 = sendHmsg($v["user_phone"],$v["user_name"]);
                    }

                    $upd["upd_time"] = time();
                    $upd["sendmsg_flag"] = 1;
                    $res3 = $order->where(["id"=>$v["id"]])->update($upd);


                }

            }

            return "success";
        }catch (\think\exception\PDOException $e){
            file_put_contents("autoPayCancelError.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$e->getMessage().PHP_EOL, FILE_APPEND);
        }


    }



    //后台接口 实时获取订单预定数量
    public function getOrderCount(){
        //获取订单未读数据 即：已预定 但未入住订单
        if($this->adminId == 1){
            //  $where1 = "pay_status = '1' and refund_status = '0' || pay_status = '2' and refund_status = '0'";
            $count  = db("order")->where("pay_status = '1' and refund_status = '0' || pay_status = '2' and refund_status = '0'")->count("id");
        }else{
            $count  = db("order")->where("pay_status = '1' and refund_status = '0' || pay_status = '2' and refund_status = '0'")->where('hotelid','in',$this->hid)->count("id");
        }


        return $count;
    }

    /*后台获取城市数据*/
    public function getAreaDown(){
        $areaid = $this->request->request("arreaid");

        if($areaid){
            $list = db("city")->field("areaId,areaName,parentId")->where(['parentId'=>$areaid])->select();
            if($list){
                return $list;
            }else{
                return [];
            }
        }else{
            return [];
        }
    }

    /*后台使用*/
    public function getRooms(){
        $hid = $this->request->request("hid");
        if($hid){
            $list = db("house")->field("id,h_id,h_housebrand,h_title")->where("h_status='normal'")->where(['h_id'=>$hid])->select();
            if($list){
                return $list;
            }else{
                return [];
            }
        }else{
            return [];
        }
    }

    /*后台获取城市商圈数据*/
    public function getcityArea(){
        $shengid = $this->request->request("shengid");//省id
        $shiid = $this->request->request("shiid");//市id

       $list = db("area")->where(['status'=>'normal'])->field("id,atitle,cityid,citydid")->where(['cityid'=>$shengid,'citydid'=>$shiid])->select();
        if($list){
            return $list;
        }else{
            return [];
        }

    }

    //退房结算
    private function checkOut($info){
        $odb = db("order");
        $rdb = db("house");
        $labeldb = db("label");
        Db::startTrans();
        //订单信息
        $oinfo = $info;
        $ordernumber = $oinfo['order_number'];

        //用户信息
        $userinfo = db("user")->where(["id"=>$oinfo['user_id']])->field("id,score,phone,nickName,money,hours")->find();

        $houseinfo = json_decode($oinfo['room_html'],true);
        //labels表 休息房、打卡房
        $labels = $houseinfo['h_lebals'];

        //酒店信息
        $hinfo = db("hotels")->where(['hid'=>$oinfo['hotelid']])->find();


        $now = time();
        //订单更新
        $orderup['upd_time'] = $now;

        if($oinfo){
            //判断支付方式 余额支付 无需走微信
            if($oinfo['pay_type'] == 1){

                //全日房 和 小时房（有结束日期） 两者情况一样
                if($oinfo['timing'] == "0" || $oinfo['timing'] == "1"){

                    //全日房 支付时 押金和基础服务费和房费都已经付款
                    //退房时 只要修改订单状态就行 无需退款
                    $orderup['pay_status'] = "3";//订单状态
                    $orderup['refund_status'] = 1;//退款状态 抵消费用 无需退款
                    $orderup['return_money'] = 0;// 无需退款 退款金额为0
                    $orderup['income'] = $oinfo['all_money'];//收入等于支付的金额
                    $orderup['checkout_time'] = $now;//退房时间
                    $eff1 = $odb->where(['order_number'=>$ordernumber])->update($orderup);

                    //回归房源状态
                    $rdata["h_statusText"] = "cleaning";
                    $rdata["updatetime"] = $now;
                    $eff2 = $rdb->where("id={$oinfo['room_id']}")->update($rdata);

                    //修改房间属性的数量 修改label表记录
                    if($labels){
                        $number = $oinfo['number'];
                        $eff3 = $labeldb->execute("UPDATE `fa_label` SET `lcount`=`lcount` + $number,`updtime`= $now WHERE  `id` in ($labels) ");
                    }else{
                        $eff3 = true;
                    }

                    if($eff1 && $eff2 && $eff3){
                        Db::commit();
                        if($userinfo["phone"]){
                            //通知用户您入住的房间已经退房
                            //sendCmsg($userinfo["phone"],$houseinfo['h_title']);
                        }
                        if($hinfo["h_phone"]){
                            //通知酒店 用户已经退房，请准时打扫
                            //sendHOmsg($userinfo["phone"],$userinfo["nickName"]);
                        }
                        file_put_contents("TaskCheckout-yue.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$eff1.",".$eff2.",".$eff3.PHP_EOL, FILE_APPEND);
                        return "success";
                    }else{
                        Db::rollback();
                        file_put_contents("TaskCheckout-error-yue.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$eff1.",".$eff2.",".$eff3.PHP_EOL, FILE_APPEND);
                        return "error";

                    }


                }else{
                    //自动退款，那就说明 时间已经到了默认时间或用户选择的时间，那么消费就是全部的 押金和基础服务费 都不用退
                    $overtimeminute = $oinfo['overtimeminute'];
                    $stime_move = $oinfo['moveinto_time'];
                    $now = $oinfo['etime'];

                    //当前时间小于入住时间 按照最低一小时扣费
                    if($now <= $stime_move){
                        $hour2 = 1;
                    }else{
                        //总之 无结束日期的小时房 最多不会超过 30个小时 如果就是超过了30小时 也按照 30小时计算
                        $countday = getDatediffedaytemp($stime_move,$now);
                        $hour = 0;
                        if($countday == 1){
                            $hour = 24;
                        }
                        $counthour = getDatediffemintemp($stime_move,$now);
                        $hour2 = floor($counthour/60) + $hour;
                        $min = ($counthour - $hour2*60);
                        if($min >= $overtimeminute){
                            $hour2++;
                        }
                    }


                    //判断是否需要退款 如果超过了一天的费用 则按照封顶价扣费
                    $price = $oinfo['price'];
                    $number = $oinfo['number'];//预定房间数量

                    $allprice = $price * $hour2;//房费
                    if($allprice >= $oinfo['totalprice']){
                        $allprice = $oinfo['totalprice'];
                    }

                    $orderup['pay_status'] = "3";//订单状态
                    $orderup['all_price'] = $allprice * $number;//实际房费
                    $orderup['refund_status'] = 3;//退款状态 抵消费用 无需退款
                    $orderup['return_money'] = 0;// 无需退款 动态计算房费
                    $orderup['income'] = $oinfo['all_money'];//收入等于支付的金额
                    $orderup['checkout_time'] = $now;//退房时间

                    $eff1 = $odb->where(['order_number'=>$ordernumber])->update($orderup);
                    //回归房源状态
                    $rdata["h_statusText"] = "cleaning";
                    $rdata["updatetime"] = $now;
                    $eff2 = $rdb->where("id={$oinfo['room_id']}")->update($rdata);

                    //修改房间属性的数量 修改label表记录
                    if($labels){
                        $number = $oinfo['number'];
                        $eff3 = $labeldb->execute("UPDATE `fa_label` SET `lcount`=`lcount` + $number,`updtime`= $now WHERE  `id` in ($labels) ");
                    }else{
                        $eff3 = true;
                    }
                    if($eff1 && $eff2 && $eff3){
                        Db::commit();
                        file_put_contents("TaskCheckout-yue2.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$eff1.",".$eff2.",".$eff3.PHP_EOL, FILE_APPEND);
                        return "success";

                    }else{
                        Db::rollback();
                        file_put_contents("TaskCheckout-error-yue2.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$eff1.",".$eff2.",".$eff3.PHP_EOL, FILE_APPEND);
                        return "error";
                    }
                }

            }else{
                //微信支付
                if($oinfo['pay_type'] == "0"){

                    //全日房 和 小时房（有结束日期） 两者情况一样
                    if($oinfo['timing'] == "0" || $oinfo['timing'] == "1"){
                        //微信支付
                        //全日房 支付时 押金和基础服务费和房费都已经付款
                        //退房时 只要修改订单状态就行 无需退款
                        $orderup['pay_status'] = "3";//订单状态
                        $orderup['refund_status'] = 1;//退款状态 抵消费用 无需退款
                        $orderup['return_money'] = 0;// 无需退款 退款金额为0
                        $orderup['income'] = $oinfo['all_money'];//收入等于支付的金额
                        $orderup['checkout_time'] = $now;//退房时间
                        $eff1 = $odb->where(['order_number'=>$ordernumber])->update($orderup);
                        //回归房源状态
                        $rdata["h_statusText"] = "cleaning";
                        $rdata["updatetime"] = $now;
                        $eff2 = $rdb->where("id={$oinfo['room_id']}")->update($rdata);

                        //修改房间属性的数量 修改label表记录
                        if($labels){
                            $number = $oinfo['number'];
                            $eff3 = $labeldb->execute("UPDATE `fa_label` SET `lcount`=`lcount` + $number,`updtime`= $now WHERE  `id` in ($labels) ");
                        }else{
                            $eff3 = true;
                        }

                        if($eff1 && $eff2 && $eff3){
                            Db::commit();
                            file_put_contents("TaskCheckout-weixin.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$eff1.",".$eff2.",".$eff3.PHP_EOL, FILE_APPEND);
                            return "success";

                        }else{
                            Db::rollback();
                            file_put_contents("TaskCheckout-error-weixin.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$eff1.",".$eff2.",".$eff3.PHP_EOL, FILE_APPEND);
                            return "error";
                        }

                    }else{

                        //自动退款，那就说明 时间已经到了默认时间或用户选择的时间，那么消费就是全部的 押金和基础服务费 都不用退
                        //余额和微信支付 没有结束日期，根据自动默认的结束时间计费，所以如果走了自动退款，等同于所有押金抵消了房费
                        $overtimeminute = $oinfo['overtimeminute'];
                        $stime_move = $oinfo['moveinto_time'];
                        $now = $oinfo['etime'];

                        if($now <= $stime_move){
                            $hour2 = 1;
                        }else{
                            //总之 无结束日期的小时房 最多不会超过 30个小时 如果就是超过了30小时 也按照 30小时计算
                            $countday = getDatediffedaytemp($stime_move,$now);
                            $hour = 0;
                            if($countday == 1){
                                $hour = 24;
                            }
                            $counthour = getDatediffemintemp($stime_move,$now);
                            $hour2 = floor($counthour/60) + $hour;
                            $min = ($counthour - $hour2*60);
                            if($min >= $overtimeminute){
                                $hour2++;
                            }
                        }


                        //判断是否需要退款 如果超过了一天的费用 则按照封顶价扣费
                        $price = $oinfo['price'];
                        $number = $oinfo['number'];//预定房间数量

                        $allprice = $price * $hour2;//房费
                        if($allprice >= $oinfo['totalprice']){
                            $allprice = $oinfo['totalprice'];
                        }

                        $orderup['all_price'] = $allprice * $number;//实际房费
                        $orderup['pay_status'] = "3";//订单状态
                        $orderup['return_money'] = 0;// 无需退款 动态计算房费
                        $orderup['refund_status'] = 3;//退款状态 抵消费用 无需退款
                        $orderup['income'] = $oinfo['all_money'];//收入等于支付的金额
                        $orderup['checkout_time'] = $now;//退房时间
                        $eff1 = $odb->where(['order_number'=>$ordernumber])->update($orderup);

                        //回归房源状态
                        $rdata["h_statusText"] = "cleaning";
                        $rdata["updatetime"] = $now;
                        $eff2 = $rdb->where("id={$oinfo['room_id']}")->update($rdata);

                        //修改房间属性的数量 修改label表记录
                        if($labels){
                            $number = $oinfo['number'];
                            $eff3 = $labeldb->execute("UPDATE `fa_label` SET `lcount`=`lcount` + $number,`updtime`= $now WHERE  `id` in ($labels) ");
                        }else{
                            $eff3 = true;
                        }
                        if($eff1 && $eff2 && $eff3){
                            Db::commit();
                            file_put_contents("TaskCheckout-weixin2.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$eff1.",".$eff2.",".$eff3.PHP_EOL, FILE_APPEND);
                            return "success";

                        }else{
                            Db::rollback();
                            file_put_contents("TaskCheckout-error-weixin2.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$eff1.",".$eff2.",".$eff3.PHP_EOL, FILE_APPEND);
                            return "error";
                        }

                    }

                }else{

                    //小时卡&微信支付 只针对小时房
                    //有结束日期的 小时房 已经 付过了，主要考虑 到底使用的小时卡是否足够
                    //由于支付时就扣掉了小时卡 并且计算出了 做多使用的小时卡数和需要微信支付的费用（基础服务费、部分房费），部分费用被全部记录到日志money2
                    //所以这里退款根据记录的费用去掉 基础服务费后如果还大于押金 则多余的费用就是额外的房费；计算房费：money2 - ballprice - despoit
                    //有结束日期，不需要押金 但基础服务费部分是必须微信付款的，所以也符合，小时卡只能抵扣房费，所以money2 就只是 基础服务费和部分房费，
                    //付款时 就把这些费用计算清楚了（如果小时卡够，直接抵扣，微信只付款基础服务费；如果小时卡不够，那就是基础服务费和部分房费），所以，退房时，无需走微信支付退款。
                    if($oinfo['timing'] == "0"){
                        $this->error("全日房不能小时卡支付");
                    }
                    if($oinfo['timing'] == "1"){

                        //微信支付 小时房 有结束日期
                        //全日房 支付时 基础服务费和房费都已经付款
                        //退房时 只要修改订单状态就行 无需退款
                        $umlog = db("user_money_log")->where(['service_ids'=>$oinfo['order_number']])->find();

                        if($umlog){
                            $hour = (int)$umlog['money'];
                            $wx_income = (float)$umlog['money2'];
                        }else{
                            $hour = 0;
                            $wx_income = 0;
                        }
                        $orderup['use_hour'] = $hour;//实际使用小时卡
                        $orderup['wx_income'] = $wx_income;//实际微信支付
                        $orderup['pay_status'] = "3";//订单状态
                        $orderup['refund_status'] = 1;//退款状态 抵消费用 无需退款
                        $orderup['return_money'] = 0;// 无需退款 退款金额为0
                        $orderup['income'] = $wx_income;// 实际微信的付款（由于小时卡购买时已经付过钱了，这里只是微信部分付款的统计）
                        $orderup['checkout_time'] = $now;//退房时间

                        $eff1 = $odb->where(['order_number'=>$ordernumber])->update($orderup);
                        //回归房源状态
                        $rdata["h_statusText"] = "cleaning";
                        $rdata["updatetime"] = $now;
                        $eff2 = $rdb->where("id={$oinfo['room_id']}")->update($rdata);

                        //修改房间属性的数量 修改label表记录
                        if($labels){
                            $number = $oinfo['number'];
                            $eff3 = $labeldb->execute("UPDATE `fa_label` SET `lcount`=`lcount` + $number,`updtime`= $now WHERE  `id` in ($labels) ");
                        }else{
                            $eff3 = true;
                        }

                        if($eff1 && $eff2 && $eff3){
                            Db::commit();
                            file_put_contents("TaskCheckout-card.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$eff1.",".$eff2.",".$eff3.PHP_EOL, FILE_APPEND);
                            return "success";
                        }else{
                            Db::rollback();
                            file_put_contents("TaskCheckout-error-card.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$eff1.",".$eff2.",".$eff3.PHP_EOL, FILE_APPEND);
                            return "error";
                        }

                    }else{

                        //无结束日期的小时房
                        //费用计算逻辑：预收全天的房费（即换算成对应的全天的小时卡数） + 微信费用（押金+基础服务）
                        //退款：根据实际情况 回退小时卡，如果小时卡充足，押金全退，如果不够，从押扣除，押金退回部分；
                        //如果是无结束日期的，会自动到12点，到时没有退房，程序会自动修改订单状态，发送短信，所以计算最迟以12点计算，超过了12点，只要退款押金即可

                        //小时卡数据
                        if($oinfo['cardid']){
                            $carddata = db("user_card")->where(['id'=>$oinfo['cardid']])->find();
                            $lesshour = $carddata["less_hours"];
                        }else{
                            $lesshour = 0;
                        }

                        //支付时写入的数据
                        $moneydata = db("user_money_log")->where(['service_ids'=>$oinfo['order_number']])->find();

                        $overtimeminute = $oinfo['overtimeminute'];
                        //入住计费时间
                        $stime_move = $oinfo['moveinto_time'];

                        $moneylog['createtime'] = $now;
                        $moneylog['user_id'] = $oinfo['user_id'];
                        $moneylog['nickname'] = $userinfo['nickName'];
                        $moneylog['memo'] = "小时卡&微信支付-".$hinfo['hoteltitle'];
                        $moneylog['service_ids'] = $oinfo['order_number'];

                        //自动计算的离开时间
                        $etime_move = $oinfo['etime'];
                        $now = $oinfo['etime'];


                        //总之 无结束日期的小时房 最多不会超过 30个小时 如果就是超过了30小时 也按照 30小时计算
                        $countday = getDatediffedaytemp($stime_move,$now);

                        $hour = 0;
                        if($countday == 1){
                            $hour = 24;
                        }

                        $counthour = getDatediffemintemp($stime_move,$now);
                        //实际入住的小时数
                        $hour2 = floor($counthour/60) + $hour;
                        $min = ($counthour - $hour2*60);
                        if($min >= $overtimeminute){
                            $hour2++;
                        }

                        //无结束日期 去最多应扣掉的小时数， 向上取整 后续根据实际情况回退 这里固定扣除一天最多10小时 配置
                        $confighour = db("config")->field("value")->where(['id'=>37])->find();
                        if($confighour && $confighour['value']){
                            $maxhour = $confighour['value'];
                        }else{
                            $maxhour = 10;
                        }

                        //小时数最多不能超过配置的
                        if($hour2 >10){
                            $hour2 = $maxhour;
                        }

                        //日志中的money 大于或者等于 $hour2
                        //$money2 是押金和基础服务费和部分房费
                        if($hour2 > $moneydata['money']){
                            $returnhourflag = false;
                            $returnhour = 0;
                            $retrunmoney = $oinfo['deposit'] - $oinfo['price'] * ($hour2-$moneydata['money']);//从押金中扣除超时的费用

                            if($retrunmoney <=0){
                                $retrunmoney = 0;
                            }
                            //实时小时大于用户已经扣掉的小时数，其余部分需要微信扣款 扣款金额 单价 * ($hour2 - $moneydata['money'])
                            //退款金额  从微信抵扣
                            $moneylog['money'] = $retrunmoney;//微信退回金额
                            $moneylog['money2'] =  $moneydata['money2'] - $oinfo['deposit'] + $oinfo['price'] * ($hour2-$moneydata['money']);//收入等于已付金额 + 超出的小时费用
                            $moneylog['type'] = 0;//微信&小时卡支付 退款到微信里 因为小时卡显示的是小时数，这里需要显示金额 所以放到微信支付下
                            $moneylog['type2'] = 1;
                            $moneylog['before'] = 0;
                            $moneylog['after'] =  0;

                            $eff1 = true;
                            $eff11 = true;
                            //房费
                            $orderup['all_price'] = $oinfo['price'] * $hour2 * $oinfo['number'];//实际房费
                            //收入
                            $orderup['income'] = $moneylog['money2'];//收入等于已付金额 + 超出的小时费用
                            $orderup['use_hour'] = $moneydata['money'];//实际使用小时卡
                            $orderup['wx_income'] = $orderup['income'];//实际微信支付 已付金额 + 超出的小时费用


                        }elseif ($hour2 == $moneydata['money']){
                            $returnhourflag = false;
                            $returnhour = 0;
                            $retrunmoney = $oinfo['deposit'];//返回全部押金
                            if($retrunmoney <=0){
                                $retrunmoney = 0;
                            }
                            //已付小时数刚好抵消 押金全退
                            $moneylog['money'] = $retrunmoney;//微信退回金额
                            $moneylog['money2'] = $moneydata['money2'] - $oinfo['deposit'];
                            $moneylog['type'] = 0;//微信&小时卡支付 退款到微信里 因为小时卡显示的是小时数，这里需要显示金额 所以放到微信支付下
                            $moneylog['type2'] = 1;
                            $moneylog['before'] = 0;
                            $moneylog['after'] =  0;
                            $eff1 = true;
                            $eff11 = true;
                            //房费
                            $orderup['all_price'] = $oinfo['price'] * $hour2 * $oinfo['number'];//实际房费
                            //收入
                            $orderup['income'] =  $moneylog['money2'] ;//相当于用户所有房费都用小时卡扣款，实际收入就是 基础服务费
                            $orderup['use_hour'] = $moneydata['money'];//实际使用小时卡
                            $orderup['wx_income'] = $orderup['income'];//实际微信支付 已付金额

                        }else{

                            $returnhourflag = true;
                            //已付小时数 大于 实际消费的
                            //回退小时卡信息 和 押金
                            $return_hour = $moneydata['money'] - $hour2;
                            $returnhour = $return_hour;
                            $retrunmoney = $oinfo['deposit'];//已付押金
                            if($retrunmoney <=0){
                                $retrunmoney = 0;
                            }
                            //追加小时卡退回记录
                            $moneylog['money'] = $return_hour;//小时卡回退0小时
                            $moneylog['money2'] =  $moneydata['money2'] - $oinfo['deposit'];
                            $moneylog['type'] = 2;
                            $moneylog['type2'] = 1;
                            $moneylog['before'] = $carddata['less_hours'];
                            $moneylog['after'] =  $carddata['less_hours'] + $return_hour;

                            $cardup['updatetime'] = $now;
                            $cardup['status'] = 1;
                            $cardup['less_hours'] = $carddata['less_hours'] + $return_hour;
                            $eff1 = db("user_card")->where(['id'=>$carddata['id']])->update($cardup);

                            //房费
                            $orderup['all_price'] = $oinfo['price'] * $hour2 * $oinfo['number'];//实际房费
                            //收入
                            $orderup['income'] =  $moneylog['money2'];// 相当于用户所有房费都用小时卡扣款，实际收入就是 基础服务费
                            $orderup['use_hour'] = $hour2;//实际使用小时卡
                            $orderup['wx_income'] = $orderup['income'];//实际微信支付 只是基础服务费

                            //追加微信退款记录
                            $moneylog22['createtime'] = $now;
                            $moneylog22['user_id'] = $oinfo['user_id'];
                            $moneylog22['nickname'] = $userinfo['nickName'];
                            $moneylog22['memo'] = "小时卡&微信支付-".$hinfo['hoteltitle'];
                            $moneylog22['service_ids'] = $oinfo['order_number'];
                            $moneylog22['money'] = $retrunmoney;//微信退款
                            $moneylog22['remark'] = "A小时卡退回：".$return_hour."小时，微信退回：".$retrunmoney."元";
                            $moneylog22['money2'] =  $return_hour;
                            $moneylog22['type'] = 0;
                            $moneylog22['type2'] = 1;
                            $moneylog22['before'] = $carddata['less_hours'];
                            $moneylog22['after'] =  $carddata['less_hours'] + $return_hour;
                            $eff11 = db("user_money_log")->insert($moneylog);

                        }
                        $moneylog['remark'] = "A自动退房执行";


                        //添加消费日志
                        $eff2 = db("user_money_log")->insert($moneylog);
                        $orderup['pay_status'] = "3";//订单状态
                        $orderup['return_money'] = $retrunmoney;// 退款金额


                        if($retrunmoney > 0){

                            //走微信退款
                            $orderup['refund_status'] = 2;//退款状态 申请退款中  等微信退款完成后 改变状态为 3
                            $refund_number = "refund_".date("YmdHis", time()) . rand(10000000, 99999999);
                            $orderup['refund_number'] = $refund_number;

                            //走微信退款流程
                            //通过微信api进行退款流程

                            $nonce_str = WxPay::str_rand();//随机32位字符串
                            $total_fee = $oinfo['all_money'] * 100;//总金额，单位：分
                            //$total_fee= 0.01 * 100;//测试 一分钱
                            $refund_fee = $retrunmoney * 100;//退款金额，单位：分
                            //$refund_fee= 0.01 * 100;//测试 一分钱
                            $parma = array(
                                'appid'=> WxPay::appid,
                                'mch_id'=> WxPay::mch_id,
                                'nonce_str'=> $nonce_str,
                                'out_trade_no'=> $oinfo['order_number'],//小程序自定义订单号，支付时后台生成
                                'out_refund_no'=> $refund_number,
                                'refund_fee'=> $refund_fee,
                                'total_fee'=> $total_fee,
                                'transaction_id' => $oinfo['transaction_id'],//小程序平台订单号，微信平台生成
                            );

                            $KEY = WxPay::key;//小程序支付秘钥
                            $parma['sign'] = $this->getSign($parma, $KEY);
                            $post_xml = $this->arrayToXml($parma);//把参数转化成xml格式
                            //向微信平台api发送退款参数
                            $xmlresult = $this->postXmlSSLCurl($post_xml,'https://api.mch.weixin.qq.com/secapi/pay/refund');
                            $array = $this->xml2array($xmlresult);
                            //两个success表示退款成功，无需使用回调，在此进行逻辑处理即可
                            if ($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS') {
                                $orderup["refund_status"] = 3;

                            }else{
                                $orderup["refund_status"] = 4;
                                $this->error("退款失败");
                            }
                            $orderup['checkout_time'] = $now;//退房时间
                            $eff3 = $odb->where(['order_number'=>$ordernumber])->update($orderup);

                            if($returnhourflag){
                                //修改用户小时卡 user表
                                $userup['hours'] = $userinfo['hours'] + $returnhour;
                                $userup['updatetime'] = $now;
                                $eff4 = db("user")->where(["id"=>$oinfo['user_id']])->update($userup);
                            }else{
                                $eff4 = true;
                            }

                            //回归房源状态
                            $rdata["h_statusText"] = "cleaning";
                            $rdata["updatetime"] = $now;
                            $eff5 = $rdb->where("id={$oinfo['room_id']}")->update($rdata);

                            //修改房间属性的数量 修改label表记录
                            if($labels){
                                $number = $oinfo['number'];
                                $eff6 = $labeldb->execute("UPDATE `fa_label` SET `lcount`=`lcount` + $number,`updtime`= $now WHERE  `id` in ($labels) ");
                            }else{
                                $eff6 = true;
                            }
                            if($eff1 && $eff2 && $eff3 && $eff4 && $eff5 && $eff6 && $eff11){
                                Db::commit();
                                file_put_contents("TaskCheckout-card2.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$eff1.",".$eff2.",".$eff3.",".$eff4.",".$eff5.",".$eff6.",".$eff11.PHP_EOL, FILE_APPEND);
                                return "success";

                            }else{
                                Db::rollback();
                                file_put_contents("TaskCheckout-error-card2.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$eff1.",".$eff2.",".$eff3.",".$eff4.",".$eff5.",".$eff6.",".$eff11.PHP_EOL, FILE_APPEND);
                                return "error";
                            }

                        }else{
                            //不走微信
                            $orderup['refund_status'] = 3;//自动完成
                            $orderup['checkout_time'] = $now;//退房时间

                            $eff3 = $odb->where(['order_number'=>$ordernumber])->update($orderup);

                            if($returnhourflag){
                                //修改用户小时卡 user表
                                $userup['hours'] = $userinfo['hours'] + $returnhour;
                                $userup['updatetime'] = $now;
                                $eff4 = db("user")->where(["id"=>$oinfo['user_id']])->update($userup);
                            }else{
                                $eff4 = true;
                            }

                            //回归房源状态
                            $rdata["h_statusText"] = "cleaning";
                            $rdata["updatetime"] = $now;
                            $eff5 = $rdb->where("id={$oinfo['room_id']}")->update($rdata);

                            //修改房间属性的数量 修改label表记录
                            if($labels){
                                $number = $oinfo['number'];
                                $eff6 = $labeldb->execute("UPDATE `fa_label` SET `lcount`=`lcount` + $number,`updtime`= $now WHERE  `id` in ($labels) ");
                            }else{
                                $eff6 = true;
                            }
                            if($eff1 && $eff2 && $eff3 && $eff4 && $eff5 && $eff6 && $eff11){
                                Db::commit();
                                file_put_contents("TaskCheckout-card3.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$eff1.",".$eff2.",".$eff3.",".$eff4.",".$eff5.",".$eff6.",".$eff11.PHP_EOL, FILE_APPEND);
                                return "success";

                            }else{
                                Db::rollback();
                                file_put_contents("TaskCheckout-error-card3.json",date("Y-m-d H:i:s")."执行成功，影响数量：".$eff1.",".$eff2.",".$eff3.",".$eff4.",".$eff5.",".$eff6.",".$eff11.PHP_EOL, FILE_APPEND);
                                return "error";
                            }

                        }

                    }

                }


            }

        }else{
            $this->error("订单数据错误");
        }

    }

    protected function getSign($params, $key)
    {
        ksort($params, SORT_STRING);
        $unSignParaString = $this->formatQueryParaMap($params, false);
        return $signStr = strtoupper(md5($unSignParaString . "&key=" . $key));
    }
    protected function formatQueryParaMap($paraMap, $urlEncode = false)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if (null != $v && "null" != $v) {
                if ($urlEncode) {
                    $v = urlencode($v);
                }
                $buff .= $k . "=" . $v . "&";
            }
        }
        $reqPar = '';
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }
    //数组转字符串方法
    protected function arrayToXml($arr){
        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {

            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }
    //获取xml里面数据，转换成array
    private function xml2array($xml)
    {
        $p = xml_parser_create();
        xml_parse_into_struct($p, $xml, $vals, $index);
        xml_parser_free($p);
        $data = [];

        foreach ($index as $key => $value) {
            if ($key == 'xml' || $key == 'XML') continue;
            $tag = $vals[$value[0]]['tag'];
            $value = $vals[$value[0]]['value'];
            $data[$tag] = $value;
        }
        return $data;
    }

    //需要使用证书的请求
    function postXmlSSLCurl($xml,$url,$second=30)
    {
        //使用的啊里云宝塔，存放证书路径，放在public中，新建cert

        $cert = '/www/wwwroot/minsuceshi/public/cert/apiclient_cert.pem';
        $key = '/www/wwwroot/minsuceshi/public/cert/apiclient_key.pem';
//        $cert = 'C:\Users\Administrator\Desktop\1602911873_20201017_cert/apiclient_cert.pem';
//         $key = 'C:\Users\Administrator\Desktop\1602911873_20201017_cert/apiclient_key.pem';
        $ch = curl_init();
        //超时时间
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        //这里设置代理，如果有的话
        //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //设置证书
        //使用证书：cert 与 key 分别属于两个.pem文件
        //默认格式为PEM，可以注释,使用getcwd()方法，拼接证书的绝对路径
        curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLCERT,$cert);

        //默认格式为PEM，可以注释,使用getcwd()方法，拼接证书的绝对路径
        curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLKEY,$key);

        //post提交方式
        curl_setopt($ch, CURLOPT_POST, true);

        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);

        $data = curl_exec($ch);

//        p($data);die;
        //返回结果
        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            echo "curl出错，错误码:$error" . "<br>";
            curl_close($ch);
            return false;
        }
    }







}
